package com.ysstech.etfmanage.thread;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Future;

import com.ysstech.common.cache.MapCacheManager;
import com.ysstech.common.enums.YssEnum;
import com.ysstech.common.exception.BusinessException;
import com.ysstech.common.service.HolidayService;
import com.ysstech.common.util.DateUtil;
import com.ysstech.etfmanage.entity.Account;
import com.ysstech.etfmanage.entity.Param;
import com.ysstech.etfmanage.entity.ParamVo;
import com.ysstech.etfmanage.feign.FeignValuationService;
import com.ysstech.etfmanage.service.ParamService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Slf4j
@Component
public class EtfAccountMainGenerator {

    @Autowired
    private ParamService paramService;
    @Autowired
    private List<EtfAccountGenerateService> etfAccountGenerateService;
    @Autowired
    private HolidayService holidayService;
    @Autowired
    private FeignValuationService feignValuationService;

    /**
     * 更新台账总入口
     *
     * @param list
     * @return
     * @throws Exception
     */

    public void renewAccount(List<String> list, Account account) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat(YssEnum.YSS_DEFAULT_DATE_TIME.getCode());
        Date startDate = sdf.parse(account.getStartDate());   // 起始日期
        Date endDate = sdf.parse(account.getEndDate());  // 结束日期
        Date tmpStartDate = startDate;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(tmpStartDate);
        Boolean falg = true;
        while (falg && tmpStartDate.getTime() <= endDate.getTime()) {
            List<Account> accountList = new ArrayList<>();
            Date date = calendar.getTime();
            if (!holidayService.isWorkDay(DateUtil.dateToStr(date))) {
                continue;
            }
            for (String accountId : list) {
                Account etfAccount = new Account();
                etfAccount.setAccountId(accountId);
                etfAccount.setPurchaseDate(DateUtil.dateToStr(date));
                accountList.add(etfAccount);
            }
            if (CollectionUtils.isEmpty(accountList)) {
                continue;
            }
            //清除行情缓存，每次重新取一遍
            String yesterday = holidayService.getNextWorkday(DateUtil.dateToStr(date), -1);
            MapCacheManager.getInstance().removeCache("QUOTATION_" + yesterday);
            MapCacheManager.getInstance().removeCache("QUOTATION_" + DateUtil.dateToStr(date));
            falg = ThreadSubmit(accountList);
            calendar.add(Calendar.DAY_OF_MONTH, 1);   // 天数加上1
            tmpStartDate = calendar.getTime();
        }
        //ThreadPool.getThreadPool().execute(new EtfAccountMain(accountList));
    }

    private Boolean ThreadSubmit(List<Account> accountList) throws Exception {
        List<Future> futureList = new ArrayList<>();
        Boolean falg = true;
        for (Account account : accountList) {
            if (null == account) {
                continue;
            }
            List<ParamVo> listParam = getParamList(account);
            if (CollectionUtils.isEmpty(listParam)) {
                continue;
            }
            listParam.forEach(etfParamVo -> {
                etfAccountGenerateService.forEach(vg -> {
                    ParamVo vo = vg.getFtype().getCode();
                    if (vo.etfMode == etfParamVo.getEtfMode() && vo.getEtfMarket().equals(etfParamVo.getEtfMarket())
                            && vo.getEtfType() == etfParamVo.getEtfType()) {
                        EtfAccountThread etf = new EtfAccountThread(vg, account, etfParamVo);
                        Future future = ThreadPool.getThreadPool().submit(etf);
                        futureList.add(future);
                    }
                });
            });
        }
        while (futureList.stream().filter(f -> !f.isDone()).count() > 0) {
            Thread.sleep(1000);
        }
        for (Future<Boolean> future : futureList) {
            if (!future.get()) {
                falg = false;
                break;
            }
        }
        return falg;
    }


    class EtfAccountMain extends Thread {
        private List<Account> accountList;

        EtfAccountMain(List<Account> accountList) {
            this.accountList = accountList;
        }

        @Override
        public void run() {
            accountList.forEach(etfAccount -> {
                try {
             /*   List<EtfParamVo> listParam = getParamList(etfAccount);
                if (CollectionUtils.isEmpty(listParam)) {
                    return;
                }*/
                    List<Future> futureList = new ArrayList<>();
                    /*            listParam.forEach(etfParamVo -> {*/
                    etfAccountGenerateService.forEach(vg -> {
                        ParamVo vo = vg.getFtype().getCode();
                   /*     if (vo.etfMode == etfParamVo.getEtfMode() && vo.getEtfMarket().equals(etfParamVo.getEtfMarket())
                                && vo.getEtfType() == etfParamVo.getEtfType()) {*/
                        EtfAccountThread etf = new EtfAccountThread(vg, etfAccount, new ParamVo());
                        Future future = ThreadPool.getThreadPool().submit(etf);
                        futureList.add(future);
                        // }
                        //  });
                    });
                    while (futureList.stream().filter(f -> !f.isDone()).count() > 0) {
                        Thread.sleep(1000);
                    }
                    for (Future<Boolean> f : futureList) {
                        if (!f.get()) {
                            throw new BusinessException("生成ETF台账出错！");
                        }
                    }
                } catch (Exception e) {
                    log.error(e.toString());
                }
            });
        }
    }


    private List<ParamVo> getParamList(Account vo) throws Exception {
        if (null == vo) {
            throw new BusinessException("获取台账信息出错，请稍后重试！");
        }
        Param param = new Param();
        param.setAccountId(vo.getAccountId());
        List<Object> paramList = paramService.getParamList(param, ParamVo.class);
        if (CollectionUtils.isEmpty(paramList)) {
            return null;
        }
        List<ParamVo> list = new ArrayList<>();
        for (Object obj : paramList) {
            ParamVo paramVo = (ParamVo) obj;
            if (null == paramVo) {
                continue;
            }
            BigDecimal etfjzbl = paramVo.getEtfBenchmarkScale();
            if (etfjzbl.compareTo(BigDecimal.ZERO) <= 0) {
                throw new BusinessException("请维护最低申赎比例！");
            }
            String etfxw = paramVo.getEtfSeat();
            if (StringUtils.isBlank(etfxw)) {
                throw new BusinessException("请维护ETF对应的席位号！");
            }
            list.add(paramVo);
        }
        return list;
    }
}
